import { _decorator, Component, Node, Sprite, Label, Color, tween, Vec3, math, v3, RigidBody2D, BoxCollider2D, Tween, sp, director, Director, Enum, Collider2D, NodePool, instantiate } from 'cc';
import { BlockType, BlockType2, GameEventType } from '../Event/EnumDefine';
import { EventManager } from '../Event/EventManager';
import { SoundManager, SoundType } from '../SoundManager';
import Common from '../Config/Common';
const { ccclass, property } = _decorator;

type BlockRecord = {
    node: Node,
    position: Vec3
}

@ccclass('Block')
export class Block extends Component {
    @property(sp.Skeleton) // 绑定 Spine 组件
    blockSpine: sp.Skeleton = null;

    @property(Node)
    blockSpine2: Node = null;

    @property(Node) 
    spineParent: Node = null;

    @property(Sprite)
    whiteSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    chengHuangSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    fenseSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    hongSeSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    huangSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    lanSeSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    lvSeSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    qianZiSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    shenZiSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Sprite)
    tianLanSprite: Sprite = null; // 某个颜色的方块图片的 Sprite 组件

    @property(Label)
    countLabel: Label = null; // 显示堆叠数量的 Label 组件

    private totalHpValue: number = 0; //当前这一叠方块的总血量值，即一开始总的数字。
    private curHpValue: number = 0; //当前这剩余血量。
    private blockCount: number = 0; // 当前堆叠的方块数量
    private blockNodes: BlockRecord[] = []; // 存储所有方块节点的数组

    private tweenList: Tween<Node>[] = []

    private stackHeight = 10;  //堆叠高度
    private riseEffectHeight = 4;  //上升高度
    private isEffectPlaying = false;  //动画效果播放中
    private blockSprite: Sprite = this.whiteSprite; // 方块图片的 Sprite 组件
    private curBlockType: BlockType;
    private blockPool: NodePool = new NodePool();

    protected start(): void {
        this.initPool();
    }

    initPool() {
        this.blockPool.clear();
        for (let i = 0; i < 200; i++) {
            const blockNode = new Node();
            blockNode.addComponent(Sprite);
            this.blockPool.put(blockNode);
        }
    }

    getBlockNode() {
        if (this.blockPool.size() === 0) {
            const blockNode = new Node();
            blockNode.addComponent(Sprite);
            this.blockPool.put(blockNode);
        }
        return this.blockPool.get();
    }

    removeBlockNode(blockNode: Node) {
        blockNode.removeFromParent();
        this.blockPool.put(blockNode);
    }

    /** 根据类型确定当前数字块颜色 */
    getBlockSprite(type: BlockType) {
        if (type === BlockType.ChengHuang) {
            this.blockSprite = this.chengHuangSprite;
        }
        else if (type === BlockType.Fense) {
            this.blockSprite = this.fenseSprite;
        }
        else if (type === BlockType.HongSe) {
            this.blockSprite = this.hongSeSprite;
        }
        else if (type === BlockType.Huang) {
            this.blockSprite = this.huangSprite;
        }
        else if (type === BlockType.LanSe) {
            this.blockSprite = this.lanSeSprite;
        }
        else if (type === BlockType.LvSe) {
            this.blockSprite = this.lvSeSprite;
        }
        else if (type === BlockType.QianZi) {
            this.blockSprite = this.qianZiSprite;
        }
        else if (type === BlockType.ShenZi) {
            this.blockSprite = this.shenZiSprite;
        }
        else if (type === BlockType.TianLan) {
            this.blockSprite = this.tianLanSprite;
        }
    }

    getBlockType2(type: BlockType){
        if (type === BlockType.ChengHuang) {
            return BlockType2.ChengHuang;
        }
        else if (type === BlockType.Fense) {
            return BlockType2.Fense;
        }
        else if (type === BlockType.HongSe) {
            return BlockType2.HongSe;
        }
        else if (type === BlockType.Huang) {
            return BlockType2.Huang;
        }
        else if (type === BlockType.LanSe) {
            return BlockType2.LanSe;
        }
        else if (type === BlockType.LvSe) {
            return BlockType2.LvSe;
        }
        else if (type === BlockType.QianZi) {
            return BlockType2.QianZi;
        }
        else if (type === BlockType.ShenZi) {
            return BlockType2.ShenZi;
        }
        else if (type === BlockType.TianLan) {
            return BlockType2.TianLan;
        }
    }

    /** 根据数字值动态分配实际创建多少个方块 */
    calculateBlockCount(count: number, total: number) {
        let value = total < 10 ? 1 : Math.ceil(total / 15);
        let number = Math.ceil(count / value);
        return number;
    }

    startGenerateBlocks(blockType: BlockType, number: number) {
        this.curBlockType = blockType;
        this.getBlockSprite(blockType);
        this.totalHpValue = number;
        this.curHpValue = number;
        this.blockCount = this.calculateBlockCount(this.curHpValue, this.totalHpValue);
        this.generateBlocks();
    }

    // 随机生成 1 到 200 个方块
    generateBlocks() {
        this.countLabel.string = this.curHpValue.toString(); // 更新 Label 显示

        for (let i = 0; i < this.blockCount; i++) {
            const blockNode = this.getBlockNode();
            const blockSprite = blockNode.getComponent(Sprite); // 添加 Sprite 组件
            blockSprite.spriteFrame = this.blockSprite.spriteFrame; // 设置 SpriteFrame

            // 设置方块的位置（逐渐往上堆叠）
            const pos = v3(0, i * this.stackHeight, 0); // 每个方块向上堆叠 10 个单位
            blockNode.setPosition(pos);
            this.node.getChildByName('ListNodes').addChild(blockNode); // 将方块节点添加到当前节点下
            const data: BlockRecord = { node: blockNode, position: pos }
            this.blockNodes.push(data); // 将方块节点存储到数组中
        }
        this.countLabel.node.setPosition(0, this.blockCount * this.stackHeight, 0); // 文字展示最上面层位置
    }

    // 方块动画：放大、闪白、恢复
    onReadyPlayEffect() {
        if (this.onClearBlock()) {
            return
        }
        this.countLabel.string = this.curHpValue.toString();
        const len = this.blockNodes.length;
        if (len <= 0) {
            return
        }
        this.isEffectPlaying = true;
        const textNode = this.countLabel.node;

        const startIndex = Math.max(0, len - 1)
        const endIndex = Math.max(0, this.blockCount - 1)
        const textOriginalPosition = this.blockNodes[startIndex].position;
        const textEndPosition = this.blockNodes[endIndex].position;
        for (let i = 0; i < len; i++) {
            let isLast = false //是否是最上面那一块方块
            if (i >= (len - 1)) {
                isLast = true;
            }
            this.playBlockRiseEffect(i, isLast)
        }
        //文字节点
        textNode.setPosition(textOriginalPosition)
        const tweenTarget = tween(textNode)
            .to(0.1, { position: new Vec3(0, textOriginalPosition.y + len * this.riseEffectHeight, 0) })
            .to(0.2, { position: textEndPosition })
            .call(() => {
                this.countLabel.string = this.curHpValue.toString();
            })
            .delay(0.01)
            .call(() => {

            })
            .start();
        this.tweenList.push(tweenTarget);
    }

    // 方块动画：上升、放大、闪白、恢复
    playBlockRiseEffect(index: number, isLast: boolean) {
        const blockNode = this.blockNodes[index].node;
        const originalPosition = this.blockNodes[index].position;
        const blockSprite = blockNode.getComponent(Sprite);
        const originalSpriteFrame = this.blockSprite.spriteFrame;  // 保存原始纹理,不用上一行的代码，是因为连续动过程中，取的上一次的纹理状态，可能会取到闪白色的纹理
        blockNode.setPosition(originalPosition)
        // 放大动画
        const tweenTarget = tween(blockNode)
            .call(() => {
                if (isLast) {
                    blockSprite.spriteFrame = this.whiteSprite.spriteFrame;
                    this.playBockPoSuiEffect2(blockNode, originalPosition);
                }
            })
            .to(0.1, { position: new Vec3(0, originalPosition.y + index * this.riseEffectHeight, 0) })
            .call(() => {
                blockSprite.spriteFrame = originalSpriteFrame;
            })
            .to(0.2, { position: originalPosition })
            .call(() => {
                if (isLast) {
                    blockSprite.spriteFrame = originalSpriteFrame;
                }
            })
            .start();
        this.tweenList.push(tweenTarget);
    }

    onClearBlock() {
        for (let i = this.blockNodes.length - 1; i >= 0; i--) {
            if (i >= this.blockCount) {
                const blockNode = this.blockNodes[i].node;
                this.removeBlockNode(blockNode);
                this.blockNodes.splice(i, 1); // 从数组中移除
            }
        }
        this.isEffectPlaying = false
        // 全部移除
        if (this.blockCount <= 0) {
            if (this.countLabel) {
                this.countLabel.node.active = false;
            }
            // 取消监听碰撞事件
            const collider = this.getComponent(Collider2D);
            if (collider) {
                collider.enabled = false;
            }
            EventManager.instance.triggerEvent(GameEventType.Block_Broken, { pos: this.node.getWorldPosition(), number: this.totalHpValue });
            // 播放碎块动画
            this.playBockPoSuiEffect();
            return true
        }
        return false
    }

    /** 播放破碎动画，结束后销毁次节点 */
    playBockPoSuiEffect() {
        if (this.blockSpine) {
            this.blockSpine.node.active = true;
            Common.instance.playSpine(this.blockSpine, this.curBlockType, false, null, () => {
                director.once(Director.EVENT_AFTER_PHYSICS, () => {
                    this.node.destroy();
                })
            });
        }
    }

    playBockPoSuiEffect2(blockNode: Node, pos: Vec3) {
        if (blockNode) {
            let spineNode = instantiate(this.blockSpine2);
            spineNode.active = true;
            spineNode.setPosition(pos);
            spineNode.setParent(this.spineParent);
            let spine = spineNode.getChildByName('spine');
            Common.instance.playSpine(spine.getComponent(sp.Skeleton), this.getBlockType2(this.curBlockType), false, null, ()=>{
                spineNode.removeFromParent();
            });
        }
    }

    onDamage(damageValue: number) {
        if (this.blockCount <= 0) {
            return;
        }
        const destroyNum = Math.floor(damageValue) * 1;      //需要销毁的方块数量
        let damage = destroyNum < this.curHpValue ? destroyNum : this.curHpValue;
        this.curHpValue = this.curHpValue - damage     //剩余未销毁的方块数量
        this.blockCount = this.calculateBlockCount(this.curHpValue, this.totalHpValue);
        this.tweenList.forEach((value) => {
            value.stop();
        })
        this.onReadyPlayEffect();
        SoundManager.instance.playSound(SoundType.Hit);
    }

    onDamageByPlayer(){
        this.curHpValue = 0;
        this.blockCount = this.calculateBlockCount(this.curHpValue, this.totalHpValue);
        this.tweenList.forEach((value) => {
            value.stop();
        })
        this.onReadyPlayEffect();
        SoundManager.instance.playSound(SoundType.Hit);
    }
}
